namespace SimpleWebServices.Web.Mvc
{
    using System;
    using System.Reflection;
    using System.Web.Routing;
    using SimpleWebServices;
    using SimpleWebServices.Web.Routing;
    using Xunit;

    public sealed class ResourceAttributeFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<ResourceAttribute>()
                .DerivesFrom<Attribute>()
                .IsConcreteClass()
                .IsSealed()
                .NoDefaultConstructor()
                .IsDecoratedWith<AttributeUsageAttribute>()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new ResourceAttribute());
        }

        [Fact]
        public void ctor_string()
        {
            Assert.NotNull(new ResourceAttribute("path"));
        }

        [Fact]
        public void ctor_stringEmpty()
        {
            Assert.NotNull(new ResourceAttribute(string.Empty));
        }

        [Fact]
        public void ctor_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute(null));
        }

        [Fact]
        public void prop_Path()
        {
            Assert.True(new PropertyExpectations(typeof(ResourceAttribute).GetProperty("Path"))
                .DefaultValueIs(string.Empty)
                .ArgumentNullException()
                .FormatException("/path")
                .Set(string.Empty)
                .Set("path")
                .Result);
        }

        [Fact]
        public void op_RegisterContentNegotiation_RouteCollection_Type()
        {
            RouteCollection routes = new RouteCollection();

            new ResourceAttribute("path").RegisterContentNegotiation(routes, typeof(NotFoundController));

            Assert.Equal<int>(2, routes.Count);
        }

        [Fact]
        public void op_RegisterContentNegotiation_RouteCollectionNull_Type()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterContentNegotiation(null as RouteCollection, typeof(NotFoundController)));
        }

        [Fact]
        public void op_RegisterContentNegotiation_RouteCollection_TypeNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterContentNegotiation(new RouteCollection(), null as Type));
        }

        [Fact]
        public void op_RegisterContentNegotiation_RouteCollection_TypeInvalid()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new ResourceAttribute("path").RegisterContentNegotiation(new RouteCollection(), typeof(string)));
        }

        [Fact]
        public void op_RegisterContentNegotiation_RouteCollection_TypeBadName()
        {
            Assert.Throws<FormatException>(() => new ResourceAttribute("path").RegisterContentNegotiation(new RouteCollection(), typeof(ControllerBadName)));
        }

        [Fact]
        public void op_RegisterLanguageNegotiation_RouteCollection_Type()
        {
            RouteCollection routes = new RouteCollection();

            new ResourceAttribute("path").RegisterLanguageNegotiation(routes, typeof(NotFoundController));

            Assert.Equal<int>(2, routes.Count);
        }

        [Fact]
        public void op_RegisterLanguageNegotiation_RouteCollectionNull_Type()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterLanguageNegotiation(null as RouteCollection, typeof(NotFoundController)));
        }

        [Fact]
        public void op_RegisterLanguageNegotiation_RouteCollection_TypeNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterLanguageNegotiation(new RouteCollection(), null as Type));
        }

        [Fact]
        public void op_RegisterLanguageNegotiation_RouteCollection_TypeInvalid()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new ResourceAttribute("path").RegisterLanguageNegotiation(new RouteCollection(), typeof(string)));
        }

        [Fact]
        public void op_RegisterLanguageNegotiation_RouteCollection_TypeBadName()
        {
            Assert.Throws<FormatException>(() => new ResourceAttribute("path").RegisterLanguageNegotiation(new RouteCollection(), typeof(ControllerBadName)));
        }

        [Fact]
        public void op_RegisterPost_RouteCollection_Type_MethodInfo()
        {
            RouteCollection routes = new RouteCollection();

            new ResourceAttribute("path").RegisterPost(routes, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("Post"));

            Assert.Equal<int>(1, routes.Count);
        }

        [Fact]
        public void op_RegisterPost_RouteCollectionNull_Type_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPost(null as RouteCollection, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("Post")));
        }

        [Fact]
        public void op_RegisterPost_RouteCollection_TypeNull_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPost(new RouteCollection(), null as Type, typeof(RouteCollectionTestController).GetMethod("Post")));
        }

        [Fact]
        public void op_RegisterPost_RouteCollection_TypeInvalid_MethodInfo()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new ResourceAttribute("path").RegisterPost(new RouteCollection(), typeof(string), typeof(RouteCollectionTestController).GetMethod("Post")));
        }

        [Fact]
        public void op_RegisterPost_RouteCollection_TypeBadName_MethodInfo()
        {
            Assert.Throws<FormatException>(() => new ResourceAttribute("path").RegisterPost(new RouteCollection(), typeof(ControllerBadName), typeof(RouteCollectionTestController).GetMethod("Post")));
        }

        [Fact]
        public void op_RegisterPost_RouteCollection_Type_MethodInfoNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPost(new RouteCollection(), typeof(RouteCollectionTestController), null as MethodInfo));
        }

        [Fact]
        public void op_RegisterPut_RouteCollection_Type_MethodInfo()
        {
            RouteCollection routes = new RouteCollection();

            new ResourceAttribute("path").RegisterPut(routes, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("Put"));

            Assert.Equal<int>(1, routes.Count);
        }

        [Fact]
        public void op_RegisterPut_RouteCollectionNull_Type_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPut(null as RouteCollection, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("Put")));
        }

        [Fact]
        public void op_RegisterPut_RouteCollection_TypeNull_MethodInfo()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPut(new RouteCollection(), null as Type, typeof(RouteCollectionTestController).GetMethod("Put")));
        }

        [Fact]
        public void op_RegisterPut_RouteCollection_TypeInvalid_MethodInfo()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new ResourceAttribute("path").RegisterPut(new RouteCollection(), typeof(string), typeof(RouteCollectionTestController).GetMethod("Put")));
        }

        [Fact]
        public void op_RegisterPut_RouteCollection_TypeBadName_MethodInfo()
        {
            Assert.Throws<FormatException>(() => new ResourceAttribute("path").RegisterPut(new RouteCollection(), typeof(ControllerBadName), typeof(RouteCollectionTestController).GetMethod("Put")));
        }

        [Fact]
        public void op_RegisterPut_RouteCollection_Type_MethodInfoNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterPut(new RouteCollection(), typeof(RouteCollectionTestController), null as MethodInfo));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_Type_MethodInfo_ContentNegotiationAttribute()
        {
            RouteCollection routes = new RouteCollection();

            new ResourceAttribute("path").RegisterRepresentation(routes, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), new ContentNegotiationAttribute(".html", "text/html"));

            Assert.Equal<int>(2, routes.Count);
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollectionNull_Type_MethodInfo_ContentNegotiationAttribute()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterRepresentation(null as RouteCollection, typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), new ContentNegotiationAttribute(".html", "text/html")));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_TypeNull_MethodInfo_ContentNegotiationAttribute()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterRepresentation(new RouteCollection(), null as Type, typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), new ContentNegotiationAttribute(".html", "text/html")));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_TypeInvalid_MethodInfo_ContentNegotiationAttribute()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new ResourceAttribute("path").RegisterRepresentation(new RouteCollection(), typeof(string), typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), new ContentNegotiationAttribute(".html", "text/html")));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_TypeBadName_MethodInfo_ContentNegotiationAttribute()
        {
            Assert.Throws<FormatException>(() => new ResourceAttribute("path").RegisterRepresentation(new RouteCollection(), typeof(ControllerBadName), typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), new ContentNegotiationAttribute(".html", "text/html")));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_Type_MethodInfoNull_ContentNegotiationAttribute()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterRepresentation(new RouteCollection(), typeof(RouteCollectionTestController), null as MethodInfo, new ContentNegotiationAttribute(".html", "text/html")));
        }

        [Fact]
        public void op_RegisterRepresentation_RouteCollection_Type_MethodInfo_ContentNegotiationAttributeNull()
        {
            Assert.Throws<ArgumentNullException>(() => new ResourceAttribute("path").RegisterRepresentation(new RouteCollection(), typeof(RouteCollectionTestController), typeof(RouteCollectionTestController).GetMethod("XmlRepresentation"), null as ContentNegotiationAttribute));
        }
    }
}